//---------------------------------------Include-----------------------------------------------------------
#include "LCD16x2.h"
//---------------------------------------------------------------------------------------------------------

//---------------------------------------Funcoes Locais----------------------------------------------------
void lcd_write_cmd(uint16_t cmd);
void lcd_write_data(uint16_t data);
void verifica_etapa(int etapa);
void set_etapa_ciclo(int etapa);
void sel_status(int status);
void trata_error(int error);
//---------------------------------------------------------------------------------------------------------
//---------------------------------------Funcoes-----------------------------------------------------------
//Delay
void delay(unsigned int s){
    while(--s > 0) {
    	__NOP();
    }
}

//Inicializa os pinos
void lcd_init_gpio() {
	GPIO_InitTypeDef  GPIO_InitStructure;
		RCC_APB2PeriphClockCmd(LCD_RCC_GPIO, ENABLE);
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_12;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(LCD_PORT, &GPIO_InitStructure);

}

//Escreve dados
void lcd_write_data(uint16_t data) {
	GPIO_SetBits(LCD_PORT,data | LCD_E_Pin);
	delay(0xFF5);
	GPIO_ResetBits(LCD_PORT,LCD_E_Pin | data);
}

//Inicializa o lcd
void lcd_init() {
	lcd_init_gpio();
	int del = (99999/25);
	GPIO_ResetBits(LCD_PORT, LCD_RS_Pin);  // rs = 0
	delay(del);

	lcd_write_data(0b00110000); //inicilizacao1
	delay(del);

	lcd_write_data(0b00110000); //inicilizacao2
	delay(del);

	lcd_write_data(0b00110000); //inicilizacao3
	delay(del);

	lcd_write_data(0b00111000); // Set comunicacao com 8bits e matrix 5x7
	delay(del);

	lcd_write_data(0b00001100); //habilita o display
	delay(del);

	lcd_write_data(0b00000001); //limpa o display
	delay(del);

	lcd_write_data(0b00000110); //entra no modo set
	delay(del);

	lcd_write_data(0b00000010); // volta para o primeiro caracter
	delay(del);

	GPIO_SetBits(LCD_PORT,LCD_RS_Pin);  //rs = 1

}

//Escreve uma palavra no lcd
void lcd_write_str(char*str) {
	do {
		lcd_write_data(*str);
	}while(*++str);
}

void lcd_write_num(int num) {
	do {
		lcd_write_data(num);
	}while(++num);
}

//Escreve um comando no lcd
void lcd_write_cmd(uint16_t cmd) {
	GPIO_ResetBits(LCD_PORT,LCD_RS_Pin);
	lcd_write_data(cmd);
	GPIO_SetBits(LCD_PORT,LCD_RS_Pin);
}

//Coloca o cursor em uma linha e em um caracter
void lcd_set_cursor(int line,int pos) {
	pos |= 0b10000000;
	if (line == 1) {
		pos += 0x40;
	}
	lcd_write_cmd(pos);
}

//Limpa a escrita do lcd
void lcd_clear(){
	int del = (99999/25);
	GPIO_ResetBits(LCD_PORT, LCD_RS_Pin);  // rs = 0
	delay(del);
	lcd_write_data(0b00000001); //clear
	delay(del);
	GPIO_SetBits(LCD_PORT,LCD_RS_Pin);  //rs = 1
}

void lcd_logo(){
	lcd_clear();
	lcd_set_cursor(2,2);
	lcd_write_str("ACQUA GELATA");
	lcd_set_cursor(1,1);
	lcd_write_str("Firmware: 2.2");
	lcd_set_cursor(1,16);
	delay_seg(2);
	lcd_lavagem(sel_lav_comp);
	LED_COMPLETA_ON
	LED_ENXAGUE_OFF
	delay_seg(3);
	lcd_lavagem(press_bt);
}
void lcd_prog_teste(){
	lcd_clear();
	lcd_set_cursor(2,2);
	lcd_write_str("ACQUA GELATA");
	lcd_set_cursor(1,1);
	lcd_write_str("PROGRAMA TESTE");
	lcd_set_cursor(1,16);
	delay_seg(2);
}
void lcd_prog_apresentacao(){
	lcd_clear();
	lcd_set_cursor(2,2);
	lcd_write_str("ACQUA GELATA");
	lcd_set_cursor(1,2);
	lcd_write_str("APRESENTACAO");
	lcd_set_cursor(1,16);
	delay_seg(2);
}
void lcd_password(){
	lcd_clear();
	lcd_set_cursor(2,5);
	lcd_write_str("SENHA:");
	lcd_set_cursor(1,4);
	lcd_write_str("- - - -");
	lcd_set_cursor(1,16);
	delay_seg(2);
}

void lcd_lavagem(int status){
	lcd_clear();
	sel_status(status);
	lcd_set_cursor(1,16);
	delay(0xFF5);
}
void sel_status(int status){
	switch(status){
	case sel_lav_comp:
		lcd_set_cursor(2,2);
		lcd_write_str("SELECIONADO:");
		lcd_set_cursor(1,0);
		lcd_write_str("LIMPEZA COMPLETA");
		break;
	case sel_enxague:
		lcd_set_cursor(2,2);
		lcd_write_str("SELECIONADO:");
		lcd_set_cursor(1,4);
		lcd_write_str("ENXAGUE");
		break;
	case lav_comp:
		lcd_set_cursor(2,5);
		lcd_write_str("INICIO");
		lcd_set_cursor(1,0);
		lcd_write_str("LIMPEZA COMPLETA");
		break;
	case enxague:
		lcd_set_cursor(2,5);
		lcd_write_str("INICIO");
		lcd_set_cursor(1,4);
		lcd_write_str("ENXAGUE");
		break;
	case press_bt:
		lcd_set_cursor(2,1);
		lcd_write_str("APERTE O BOTAO");
		lcd_set_cursor(1,4);
		lcd_write_str("INICIAR");
		break;
	case interrupcao:
		lcd_set_cursor(2,4);
		lcd_write_str("PROCESSO");
		lcd_set_cursor(1,2);
		lcd_write_str("INTERROMPIDO");
		break;
	default:
		break;
	}
}

void lcd_set_etapa(int timer, int etapa){
	char ch[1];
	if (timer == -1) {
		verifica_etapa(etapa);
	}
	else if(timer == -2){
		lcd_set_cursor(1,0);
		verifica_etapa(etapa);
		lcd_set_cursor(1,7);
		sprintf(ch,"%d",timer);
		lcd_write_str(ch);
		lcd_write_str(" seg    ");
		lcd_set_cursor(1,16);
		delay(200000);
	}
	else if(timer != -1 && timer != -2){
		lcd_set_cursor(1,0);
		verifica_etapa(etapa);
		lcd_set_cursor(1,7);
		sprintf(ch,"%d",timer);
		lcd_write_str(ch);
		lcd_write_str(" min    ");
		lcd_set_cursor(1,16);
		delay(200000);
	}
}

void lcd_set_etapa_APRE(int timer, int etapa){
	char ch[1];
	if (timer == -1) {
		verifica_etapa(etapa);
	}
	else if(timer != -1){
		lcd_set_cursor(1,0);
		verifica_etapa(etapa);
		lcd_set_cursor(1,7);
		sprintf(ch,"%d",timer);
		lcd_write_str(ch);
		lcd_write_str(" seg    ");
		lcd_set_cursor(1,16);
		delay(200000);
	}
}

void verifica_etapa(int etapa){
	switch(etapa){
	case ETAPA1:
		lcd_write_str("ETAPA1: ");
		break;
	case ETAPA2:
		lcd_write_str("ETAPA2: ");
		break;
	case ETAPA3:
		lcd_write_str("ETAPA3: ");
		break;
	case ETAPA4:
		lcd_write_str("ETAPA4: ");
		break;
	case ETAPA5:
		lcd_write_str("ETAPA5: ");
		break;
	case ETAPA6:
		lcd_write_str("ETAPA6: ");
		break;
	case ETAPA7:
		lcd_write_str("ETAPA7: ");
		break;
	case enx:
		lcd_clear();
		lcd_write_str("Confg tempo");
		delay_seg(3);
		lcd_clear();
		lcd_write_str("Confg enxague:");
		break;
	case comp:
		lcd_clear();
		lcd_write_str("Confg completa:");
		break;
	case sucesso:
		lcd_clear();
		lcd_set_cursor(2,2);
		lcd_write_str("Configurado");
		break;
	default:
		break;
	}
}
void lcd_etapa(int etapa, int inicio){
	lcd_clear();
	if(inicio == 1){
		lcd_set_cursor(2,5);
		lcd_write_str("INICIO");
	}
	else {
		lcd_set_cursor(2,7);
		lcd_write_str("FIM");
	}
	lcd_set_cursor(1,4);
	lcd_write_str("ETAPA: ");
	switch(etapa){
	case ETAPA1:
		lcd_write_str("1");
		break;
	case ETAPA2:
		lcd_write_str("2");
		break;
	case ETAPA3:
		lcd_write_str("3");
		break;
	case ETAPA4:
		lcd_write_str("4");
		break;
	case ETAPA5:
		lcd_write_str("5");
		break;
	case ETAPA6:
		lcd_write_str("6");
		break;
	case ETAPA7:
		lcd_write_str("7");
		break;
	default:
		break;
	}
	lcd_set_cursor(1,16);
	delay(0xFFFFF);
}

void lcd_dig_password(int pos, int senha){
	char c[1];
	switch(pos){
	case pos1:
		sprintf(c,"%d",senha);
		lcd_set_cursor(1,4);
		lcd_write_str(c);
		lcd_set_cursor(1,16);
		break;
	case pos2:
		sprintf(c,"%d",senha);
		lcd_set_cursor(1,6);
		lcd_write_str(c);
		lcd_set_cursor(1,16);
		break;
	case pos3:
		sprintf(c,"%d",senha);
		lcd_set_cursor(1,8);
		lcd_write_str(c);
		lcd_set_cursor(1,16);
		break;
	case pos4:
		sprintf(c,"%d",senha);
		lcd_set_cursor(1,10);
		lcd_write_str(c);
		lcd_set_cursor(1,16);
		break;
	case pos_fim:
		break;
	}
}

void lcd_asteristico(int pos){
	switch(pos){
	case pos1:
		lcd_set_cursor(1,4);
		lcd_write_str("*");
		break;
	case pos2:
		lcd_set_cursor(1,6);
		lcd_write_str("*");
		break;
	case pos3:
		lcd_set_cursor(1,8);
		lcd_write_str("*");
		break;
	case pos4:
		lcd_set_cursor(1,10);
		lcd_write_str("*");
		break;
	default:
		break;
	}
}

void lcd_right_pass(){
	lcd_clear();
	lcd_set_cursor(2,5);
	lcd_write_str("SENHA");
	lcd_set_cursor(1,4);
	lcd_write_str("CORRETA");
	lcd_set_cursor(1,16);
	delay_seg(2);
}

void lcd_wrong_pass(){
	lcd_clear();
	lcd_set_cursor(2,5);
	lcd_write_str("SENHA");
	lcd_set_cursor(1,3);
	lcd_write_str("INCORRETA");
	lcd_set_cursor(1,16);
	delay_seg(2);
}

void lcd_acionamento(int etapa){
	lcd_clear();
	set_etapa_ciclo(etapa);
	lcd_set_cursor(1,16);
	delay(0xFF5);
}

void set_etapa_ciclo(int etapa){
	switch(etapa){
	case ETAPA1:
	case ETAPA4:
		lcd_set_cursor(2,2);
		lcd_write_str("ABASTECENDO");
		lcd_set_cursor(1,4);
		lcd_write_str("COM AGUA");
		break;
	case ETAPA2:
		lcd_set_cursor(2,5);
		lcd_write_str("BOMBA");
		lcd_set_cursor(1,4);
		lcd_write_str("ACIONADA");
		break;
	case ETAPA3:
	case ETAPA7:
		lcd_set_cursor(2,4);
		lcd_write_str("DRENANDO");
		break;
	case ETAPA5:
		lcd_set_cursor(2,2);
		lcd_write_str("DETERGENTE E");
		lcd_set_cursor(1,2);
		lcd_write_str("AQUECIMENTO");
		break;
	case ETAPA6:
		lcd_set_cursor(2,4);
		lcd_write_str("BOMBA E");
		lcd_set_cursor(1,2);
		lcd_write_str("AQUECIMENTO");
		break;
	case ETAPA8:
		lcd_set_cursor(2,1);
		lcd_write_str("TEMPERATURA DA");
		lcd_set_cursor(1,3);
		lcd_write_str("AGUA: 60");
		lcd_write_data(223);
		lcd_write_str("C");
		break;
	case FINAL:
		lcd_set_cursor(2,5);
		lcd_write_str("FIM DA");
		lcd_set_cursor(1,4);
		lcd_write_str("LIMPEZA");
	default:
		break;
	}
}

void lcd_rest_fabrica(int status){
	lcd_clear();
	switch(status){
	case nenhum:
		lcd_set_cursor(2,0);
		lcd_write_str("RESTAURAR CONFIG DE FABRICA?");
		lcd_set_cursor(1,2);
		lcd_write_str("DE FABRICA?");
		break;
	case cancela:
		lcd_set_cursor(2,2);
		lcd_write_str("RESTAURACAO");
		lcd_set_cursor(1,3);
		lcd_write_str("CANCELADA");
		break;
	case confirma:
		lcd_set_cursor(2,2);
		lcd_write_str("RESTAURACAO");
		lcd_set_cursor(1,3);
		lcd_write_str("CONCLUIDA");
		break;
	default:
		break;
	}
	lcd_set_cursor(1,16);
}

void lcd_error(int error){
	lcd_clear();
	lcd_set_cursor(2,0);
	trata_error(error);
	lcd_set_cursor(1,16);
}
void trata_error(int error){
	switch(error){
	case clear:
		lcd_write_str("ERROR: 101");
		lcd_set_cursor(1,0);
		lcd_write_str("CLEAR MEMORY");
		break;
	case write:
		lcd_write_str("ERROR: 102");
		lcd_set_cursor(1,0);
		lcd_write_str("WRITE MEMORY");
		break;
	default:
		break;
	}
}

void lcd_time(uint16_t time){
	char c[1];
	int process;
	if(retorna_process() == O_COMPLETA)
		process = (2*timer.bkp.ciclo_ETAPA1) + (2*timer.bkp.ciclo_ETAPA2) + (2*timer.bkp.ciclo_ETAPA3) + timer.bkp.ciclo_ETAPA4 + timer.bkp.ciclo_ETAPA5 + timer.bkp.ciclo_ETAPA6 + timer.bkp.ciclo_ETAPA7;
	else if(retorna_process() == O_ENXAGUE)
		process = timer.bkp.ciclo_ETAPA1 + timer.bkp.ciclo_ETAPA2 + timer.bkp.ciclo_ETAPA3;

	process -= time;

	lcd_clear();
	lcd_set_cursor(2,0);
	lcd_write_str("FIM DO PROCESSO");

	switch((process/60)){
	case 1:
		lcd_set_cursor(1,1);
		lcd_write_str("EM 1 H ");
		sprintf(c,"%d",(process-60));
		lcd_write_str(c);
		lcd_write_str(" MIN");
		break;
	case 2:
		lcd_set_cursor(1,1);
		lcd_write_str("EM 2 H ");
		sprintf(c,"%d",(process-120));
		lcd_write_str(c);
		lcd_write_str(" MIN");
		break;
	case 3:
		lcd_set_cursor(1,1);
		lcd_write_str("EM 3 H ");
		sprintf(c,"%d",(process-180));
		lcd_write_str(c);
		lcd_write_str(" MIN");
		break;
	case 4:
		lcd_set_cursor(1,1);
		lcd_write_str("EM 4 H ");
		sprintf(c,"%d",(process-240));
		lcd_write_str(c);
		lcd_write_str(" MIN");
		break;
	case 5:
		lcd_set_cursor(1,1);
		lcd_write_str("EM 5 H ");
		sprintf(c,"%d",(process-300));
		lcd_write_str(c);
		lcd_write_str(" MIN");
		break;
	default:
		lcd_set_cursor(1,3);
		lcd_write_str("EM ");
		sprintf(c,"%d",process);
		lcd_write_str(c);
		lcd_write_str(" MIN");
		break;
	}
	lcd_set_cursor(1,16);
}
//---------------------------------------------------------------------------------------------------------
